from flask import g
from flask_restful import Resource
from flask_restful.inputs import regex
from flask_restful.reqparse import RequestParser
from sqlalchemy.orm import load_only

from app import db
from models.article import Comment, Article
from utils.decorators import login_required
from models.user import User


class CommentsResource(Resource):
    method_decorators = {'post': [login_required]}

    def post(self):
        """发布评论  回复评论"""
        # 获取参数
        userid = g.userid
        parser = RequestParser()
        parser.add_argument('target', required=True, location='json', type=int)
        parser.add_argument('content', required=True, location='json', type=regex(r'.+'))
        """回复评论 对发布评论接口进行改造,让其同时可以实现发布和回复评论两个功能"""
        parser.add_argument('parent_id', location='json', type=int)
        args = parser.parse_args()
        target = args.target
        content = args.content
        parent_id = args.parent_id

        # 判断 发布(父)评论 / 回复(子)评论
        if parent_id:   # 子评论
            # 新增子评论记录
            sub_comment = Comment(user_id=userid, article_id=target, content=content, parent_id=parent_id)
            db.session.add(sub_comment)

            # 让父评论的回复数量+1
            Comment.query.filter(Comment.id == parent_id).update({'reply_count': Comment.reply_count + 1})

            # 提交事务
            db.session.commit()

            # 返回结果
            return {'com_id': sub_comment.id, 'target': target, 'parent_id': parent_id}

        else:   # 发布评论
            # 添加评论数据
            comment = Comment(user_id=userid, article_id=target, content=content, parent_id=0)
            db.session.add(comment)

            # 让文章的评论数量+1
            Article.query.filter(Article.id == target).update({'comment_count': Article.comment_count + 1})

            # 提交事务
            db.session.commit()

            # 返回结果
            return {'com_id': comment.id, 'target': target}

    def get(self):
        """获取评论列表   回复列表"""
        # 获取参数
        parser = RequestParser()
        # 请求参数 args 查询字符串传参
        # 文章id
        parser.add_argument('source', required=True, location='args', type=int)
        # 评论数据的偏移量(基于该字段分页进行查询), 值为评论id,表示从该id的后边开始取,不传表示从头开始取
        parser.add_argument('offset', default=0, location='args', type=int)
        # 获取的评论条数
        parser.add_argument('limit', default=10, location='args', type=int)
        """回复列表  对评论列表接口进行改造,让其同时可以实现 获取评论列表和回复列表两个功能"""
        # type  数据类型   a 评论列表  c 回复列表
        parser.add_argument('type', required=True, location='args', type=regex(r'[ac]'))
        args = parser.parse_args()
        source = args.source
        offset = args.offset
        page_count = args.limit
        type = args.type

        # 判断获取 评论列表/回复列表
        if type == 'a':     # 评论列表
            # 数据库查询 文章的评论列表 & 分页 (评论id > offset参数)
            data = db.session.query(Comment.id, Comment.user_id, User.name, User.profile_photo, Comment.ctime, Comment.content, Comment.reply_count, Comment.like_count).\
                join(User, Comment.user_id == User.id).\
                filter(Comment.article_id == source, Comment.id > offset, Comment.parent_id == 0).\
                limit(page_count).all()

            # 查询评论总数
            total_count = Comment.query.filter(Comment.article_id == source, Comment.parent_id == 0).count()

            # 所有评论中最后一条评论的id    end_comment 最后一条评论对象
            # end_comment = db.session.query(Comment.id).filter(Comment.article_id == source).order_by(
            #     Comment.id.desc()).first()
            # load_only 查询指定字段
            end_comment = Comment.query.options(load_only(Comment.id)).filter(Comment.article_id == source, Comment.parent_id == 0).order_by(
                Comment.id.desc()).first()

        else:   # 回复列表
            # 查询某条评论的回复列表
            data = db.session.query(Comment.id, Comment.user_id, User.name, User.profile_photo, Comment.ctime,Comment.content, Comment.reply_count, Comment.like_count). \
                join(User, Comment.user_id == User.id). \
                filter(Comment.parent_id == source, Comment.id > offset). \
                limit(page_count).all()

            # 查询某条评论的回复总数
            total_count = Comment.query.filter(Comment.parent_id == source).count()

            # 指定评论的回复列表中最后一条回复的id
            end_comment = db.session.query(Comment.id).filter(Comment.parent_id == source).order_by(
                Comment.id.desc()).first()

        # 构造响应数据
        comment_list = [{
            "com_id": item.id,
            'aut_id': item.user_id,
            'aut_name': item.name,
            'aut_photo': item.profile_photo,
            'pubdate': item.ctime.isoformat(),
            'content': item.content,
            'reply_count': item.reply_count,
            'like_count': item.like_count
        } for item in data]

        end_id = end_comment.id if end_comment else None

        # 获取本次请求最后一条数据的id
        last_id = data[-1].id if data else None

        # 返回数据
        return {'results': comment_list, 'total_count': total_count, 'last_id': last_id, 'end_id': end_id}
